/* 对象流
既然基本数据类型能够读取和写入基本数据类型，那么能否将对象也支持呢？ObjectOutputStream不仅支持基本数据类型，通过对对象的序列化操作，以某种格式保存对象
来支持对象类型的IO，注意，它不是继承自FilterOutputStream的
 */
package javaio.ObjectInputOutputStream;

import java.io.*;

public class Main {
    public static void main(String[] args) {
        try(ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("output.txt"));
            ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("output.txt"))){
            People p = new People("lbw");  //创建一个People对象
            objectOutputStream.writeObject(p);  //往输出流里写对象，二进制的形式存储的
            objectOutputStream.flush();
            People p2 = new People("");
            p2 = (People) objectInputStream.readObject();  //不是字符串，得用readObject读取Object对象，转换为People类型
            System.out.println(p.name);
        }catch (IOException | ClassNotFoundException e){
                e.printStackTrace();
        }
    }

    static class People implements Serializable{  //定义一个往文件里存的对象类型，People类
        //必须实现Serializable序列化接口才能被序列化，不实现序列化接口会报错,报NotSerializableException不可序列化错误
        //我的理解是，必须要把对象序列化才能以二进制形式读对象写对象操作文件，如果不实现序列化接口，无法序列化，就无法以二进制形式操作对象了。

        /*
        在后续操作中，有可能会使得这个类的一些结构发生变化，而原来保存的数据只适用于之前版本的这个类，因此我们需要一种不同的方法来区分类的不同版本。
        */
        private static final long serialVersionUID = 1234567;  //我们可以自己手动指定SerialVersionUID,而不是用java计算生成的
        //如果修改了版本号，即使类里什么都没变，依然无法完成类的实例化
        //会报错，本地的class不兼容，类的流序列化版本UID(SerialVersionUID)是这个（java自己计算生成的一串数字）
        // 而本地类的序列号版本是另一个随机数(SerialVersionUID)（java自己计算生成的一串数字），无法完成实例化

        String name;
        transient int age; //增加一个成员变量，类的版本就会改变，可以使用transient关键字表示这个成员属性不参与序列化，即使序列化版本UID变了，也不影响
        //其实我们可以看到，在一些JDK内部的源码中，存在大量的transient关键字，使得某些属性不参与序列化，取消这些不必须要保存的属性，节省数据空间，减少序列化时间

        public People(String name){
            this.name = name;
        }
    }



}
